package org.jsola.hr.web;

import org.jsola.admin.entity.SiteDO;
import org.jsola.approval.vo.ApproFlowListVO;
import org.jsola.autoconfigure.jwt.SecurityContext;
import org.jsola.common.FileKit;
import org.jsola.core.Page;
import org.jsola.core.Result;
import org.jsola.exception.ParamException;
import org.jsola.file.common.FileUtil;
import org.jsola.file.entity.FileVersionDO;
import org.jsola.hr.constant.*;
import org.jsola.hr.dto.*;
import org.jsola.hr.dto.excel.EmpInfoImportDTO;
import org.jsola.hr.entity.EmpInfoDO;
import org.jsola.hr.exception.HrException;
import org.jsola.hr.provider.IAdminProviderService;
import org.jsola.hr.provider.IApproProviderService;
import org.jsola.hr.provider.IUserProviderService;
import org.jsola.hr.query.*;
import org.jsola.hr.service.*;
import org.jsola.hr.task.SendNoticeTask;
import org.jsola.hr.vo.*;
import org.jsola.hr.vo.excel.ParseResultVO;
import org.jsola.notice.constant.NoticeConstants;
import org.jsola.permission.exception.PermissionException;
import org.jsola.user.core.TokenUser;
import org.jsola.user.core.UserContext;
import org.jsola.user.dto.UpdateByPhoneDTO;
import org.jsola.user.entity.ThirdInfoDO;
import org.jsola.user.entity.UserDO;
import org.jsola.user.vo.UserSettingVO;
import org.jsola.user.vo.UserVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import java.io.File;
import java.util.*;
import java.util.stream.Collectors;

import static org.jsola.file.constant.FileConstants.DOWNLOAD_TYPE_ATTACHMENT;
import static org.jsola.hr.constant.HrPermissionConstants.COMPANY_PEOPLE_LIST;
import static org.jsola.hr.constant.HrPermissionConstants.PERMISSION_DENIED_MESSAGE;


/**
 * 员工信息
 *
 * @author zhr
 */
@RestController("hrEmpInfoController")
@RequestMapping(HrConstants.API_PATH + "/v1/empInfos")
public class EmpInfoController implements IEmpInfoControllerAPI {

    @Autowired
    private IEmpInfoService empInfoService;

    @Autowired
    private IEmpSendSmsService empSendSmsService;

    @Autowired
    private IApproProviderService approProviderService;

    @Autowired
    private IUserProviderService userProviderService;

    @Autowired
    private IHrPermissionService hrPermissionService;

    @Autowired
    private ICompanyService companyService;

    @Autowired
    private ICheckInPeopleService checkInPeopleService;

    @Autowired
    private IEmpInfoExtraService empInfoExtraService;

    @Autowired
    private SendNoticeTask sendNoticeTask;

    @Override
    @PostMapping("/getEmpJoinDate")
    public Result<Long> getEmpJoinDate(@Valid @RequestBody EmpListQuery empListQuery) {
        TokenUser tokenUser = UserContext.getUser();
        ParamException.isTrue(!CollectionUtils.isEmpty(empListQuery.getEmpIdList()), "未选择员工");
        return Result.success(
                empInfoService.getEmpJoinDate(empListQuery, tokenUser)
        );
    }

    @Override
    @PutMapping("/batchUpdateSalaryInfo")
    public Result<Integer> batchUpdateSalaryInfo(@Valid @RequestBody EmpInfoUpdateDTO empInfoUpdateDTO) {
        TokenUser tokenUser = UserContext.getUser();
        return Result.success(
                empInfoService.batchUpdateSalaryInfo(empInfoUpdateDTO, tokenUser)
        );
    }

    @GetMapping("/runTask/{taskType}/{param}")
    public Result<EmpInfoVO> runTask(@PathVariable String taskType, @PathVariable String param) {
        if (StringUtils.isEmpty(param) || !"test".equals(param)) {
            param = "";
        }
        TokenUser tokenUser = UserContext.getUser();
        // todo 新增员工信息权限校验
        if (NoticeConstants.RETIRE.equals(taskType)) {
            sendNoticeTask.retireTask(param);
        } else if (NoticeConstants.CONTRACT_EXPIRES.equals(taskType)) {
            sendNoticeTask.contractExpireTask(param);
        }
        return Result.success(
                null
        );
    }

    @Override
    @PostMapping
    public Result<EmpInfoVO> save(@Valid @RequestBody EmpInfoAddDTO empInfoAddDTO) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 新增员工信息权限校验

        return Result.success(
                empInfoService.save(empInfoAddDTO, tokenUser)
        );
    }


    @Override
    @PutMapping
    public Result<Integer> update(@Valid @RequestBody EmpInfoUpdateDTO empInfoUpdateDTO) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 修改员工信息权限校验

        int count = empInfoService.update(empInfoUpdateDTO, tokenUser);
        if (count == 0) {
            throw new ParamException("更新失败，请刷新页面后重试");
        }
        return Result.success(count);
    }


    @Override
    @DeleteMapping(value = "/{empInfoId}")
    public Result<Integer> delete(@PathVariable String empInfoId) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 删除员工信息权限校验

        int count = empInfoService.deleteByIds(tokenUser, empInfoId);
        if (count == 0) {
            throw new ParamException("删除失败，请刷新页面后重试");
        }
        return Result.success(count);
    }

    @Override
    @DeleteMapping
    public Result<Integer> deleteBatch(@RequestBody String[] empInfoIds) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 批量彻底删除员工信息权限校验

        int count = empInfoService.deleteByIds(tokenUser, empInfoIds);
        if (count == 0) {
            throw new ParamException("删除失败，请刷新页面后重试");
        }
        return Result.success(count);
    }

    @Override
    @GetMapping(value = "/{empInfoId}")
    public Result<EmpInfoVO> findById(@PathVariable String empInfoId,
                                      @RequestParam("companyId") String companyId) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看员工信息权限校验
        EmpInfoVO empInfoVO = empInfoService.selectById(empInfoId, tokenUser.getSiteId());
        if (Objects.nonNull(empInfoVO) && !empInfoVO.getCompanyId().equals(companyId)) {
            return Result.success();
        }
        return Result.success(empInfoVO);
    }

    @Override
    @GetMapping(value = "/listAll")
    public Result<List<EmpInfoListVO>> listAll(@Valid EmpInfoQuery empInfoQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看员工信息权限校验

        return Result.success(
                empInfoService.select(empInfoQuery, tokenUser)
        );
    }


    @Override
    @GetMapping
    public Result<Page<EmpInfoListVO>> page(@Valid EmpInfoQuery empInfoQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        return Result.success(
                empInfoService.selectPage(empInfoQuery, tokenUser)
        );
    }

    @Override
    @GetMapping(value = "/getEmpInfoCount/{companyId}")
    public Result<EmpInfoCountVO> getEmpInfoCount(@PathVariable String companyId) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看员工信息权限校验

        return Result.success(
                empInfoService.getEmpInfoCount(companyId, tokenUser)
        );
    }

    @Override
    @GetMapping(value = "/onJobFlows/{companyId}")
    public Result<List<ApproFlowListVO>> listOnJobCanUseFlowsByCompany(@PathVariable String companyId) {
        TokenUser tokenUser = UserContext.getUser();

        return Result.success(
                approProviderService.listOnJobCanUseFlowsByCompany(companyId, tokenUser)
        );
    }

    @Override
    @GetMapping(value = "/leavingFlows/{companyId}")
    public Result<List<ApproFlowListVO>> listLeavingCanUseFlowsByCompany(@PathVariable String companyId) {
        TokenUser tokenUser = UserContext.getUser();

        return Result.success(
                approProviderService.listLeavingCanUseFlowsByCompany(companyId, tokenUser)
        );
    }

    @Override
    @GetMapping(value = "/pageEmpList/{signingStatus}")
    public Result<Page<EmpInfoContractVO>> pageEmpListBySigningStatus(EmpListQuery empListQuery, @PathVariable() Integer signingStatus) {
        TokenUser tokenUser = UserContext.getUser();
        return Result.success(empInfoService.pageEmpListBySigningStatus(empListQuery, tokenUser, signingStatus));
    }

    @Override
    @PostMapping("/selectEmpByCardAndSalaryType")
    public Result<EmpInfoPasteVO> selectEmpByCardAndSalaryType(@Valid @RequestBody EmpInfoQuery empInfoQuery) {
        TokenUser tokenUser = UserContext.getUser();
        return Result.success(empInfoService.selectEmpByCardAndSalaryType(empInfoQuery, tokenUser));
    }

    @Override
    @PostMapping(value = "/selectEmpInfoByIdCardsAddConUse/{companyId}")
    public Result<EmpInfoPasteVO> selectEmpInfoByIdCardsAddConUse(@RequestBody String[] idCards, @PathVariable String companyId) {
        TokenUser tokenUser = UserContext.getUser();

        return Result.success(empInfoService.selectEmpInfoByIdCardsAddConUse(idCards, companyId, tokenUser));
    }

    @Override
    @GetMapping(value = "/transferDutyFlows/{companyId}")
    public Result<List<ApproFlowListVO>> listTransferDutyCanUseFlowsByCompany(@PathVariable String companyId) {
        TokenUser tokenUser = UserContext.getUser();

        return Result.success(
                approProviderService.listTransferDutyCanUseFlowsByCompany(companyId, tokenUser)
        );
    }

    @Override
    @GetMapping(value = "/turnStraightFlows/{companyId}")
    public Result<List<ApproFlowListVO>> listTurnStraightCanUseFlowsByCompany(@PathVariable String companyId) {
        TokenUser tokenUser = UserContext.getUser();

        return Result.success(
                approProviderService.listTurnStraightCanUseFlowsByCompany(companyId, tokenUser)
        );
    }

    @Override
    @GetMapping(value = "/reimbursement/{companyId}")
    public Result<List<ApproFlowListVO>> listReimbursementCanUseFlowsByCompany(@PathVariable String companyId) {
        TokenUser tokenUser = UserContext.getUser();

        return Result.success(
                approProviderService.listReimbursementCanUseFlowsByCompany(companyId, tokenUser)
        );
    }

    @Override
    @GetMapping(value = "/leave/{companyId}")
    public Result<List<ApproFlowListVO>> listLeaveCanUseFlowsByCompany(@PathVariable String companyId) {
        TokenUser tokenUser = UserContext.getUser();

        return Result.success(
                approProviderService.listLeaveCanUseFlowsByCompany(companyId, tokenUser)
        );
    }

    @Override
    @PostMapping(value = "saveEmpInfoPre")
    public Result<String> saveEmpInfoPre(@Valid @RequestBody EmpInfoOnJobDTO empInfoOnJobDTO) {
        TokenUser tokenUser = UserContext.getUser();

        if (StringUtils.isEmpty(empInfoOnJobDTO.getCompanyId())) {
            return Result.fail("请传递公司id");
        }
        //查询当前员工手机号是否已开通过用户
        UserDO userDO = userProviderService.selectByPhone(empInfoOnJobDTO.getPhone());
        if (Objects.nonNull(userDO)) {
            //员工手机号已开通过用户，提示直接添加在职员工
            return Result.fail("该员工手机号已开通过用户，请直接添加员工");
        }
        // 员工变动状态（0：当前无变动，1：转正中，2：调岗中，3： 离职中）
        empInfoOnJobDTO.setChangeStatus(0);
        empInfoOnJobDTO.setStatus(EmpInfoStatus.WAIT_ENTRY.getValue());
        empInfoOnJobDTO.setJoinFormStatus(false);
        Result result = checkEmpNumberAndPhone("", empInfoOnJobDTO.getCompanyId(), empInfoOnJobDTO.getPhone(), empInfoOnJobDTO.getNumber(), empInfoOnJobDTO.getStatus(), tokenUser);
        if (!result.getSuccess()) {
            return Result.fail(result.getMsg());
        }
        empInfoService.saveOnJobEmpInfo(empInfoOnJobDTO, tokenUser);
        return Result.success("员工入职审批发起成功,请耐心等待入职审批结果");
    }

    @Override
    @PutMapping(value = "confirmToJoin")
    public Result<String> confirmToJoin(@Valid @RequestBody EmpInfoUpdateDTO empInfoUpdateDTO) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 修改员工信息权限校验

        EmpInfoDO empInfoDO = empInfoService.selectDOById(empInfoUpdateDTO.getId(), tokenUser.getSiteId());
        if (Objects.isNull(empInfoDO)) {
            return Result.fail("员工信息不正确或已删除");
        } else if (!empInfoDO.getStatus().equals(EmpInfoStatus.WAIT_ENTRY.getValue())) {
            return Result.fail("员工已不是待入职状态,不需要确认到岗");
        } else if (empInfoDO.getApprovalStatus() == null) {
            return Result.fail("员工入职审批状态不正确,请联系管理员");
        } else if (!empInfoDO.getApprovalStatus().equals(ApprovalStatusEnum.APPRO_SUCCESS.getValue())
                && !empInfoDO.getApprovalStatus().equals(ApprovalStatusEnum.APPRO_DISABLE.getValue())) {
            return Result.fail("员工入职审批不通过,不能确认到岗");
        }

        if (empInfoUpdateDTO.getPostType() == null) {
            empInfoUpdateDTO.setPostType(PostType.LABOUR.getValue());
        }

        if (empInfoUpdateDTO.getJoinDate() == null) {
            return Result.fail("请填写正确的员工入职时间");
        }

        empInfoService.confirmToJoin(empInfoUpdateDTO, tokenUser);
        return Result.success("确认到岗成功");
    }

    @Override
    @PutMapping(value = "batchConfirmToJoin")
    public Result<Integer> batchConfirmToJoin(@Valid List<EmpInfoUpdateDTO> empInfoUpdateDTOList) {
        TokenUser tokenUser = UserContext.getUser();

        ParamException.notEmpty(empInfoUpdateDTOList, "员工不能为空");

        int result = empInfoService.batchConfirmToJoin(empInfoUpdateDTOList, tokenUser);

        //更新员工的 “信息补充 未完善、已完善”
        List<String> list = empInfoUpdateDTOList.stream().map(EmpInfoUpdateDTO::getId).collect(Collectors.toList());
        empInfoService.empCompleteInfo(list, tokenUser);

        return Result.success(result);
    }

    @Override
    @PutMapping(value = "batchNoArrival")
    public Result<Integer> batchNoArrival(@RequestBody String[] empIds) {
        TokenUser tokenUser = UserContext.getUser();

        ParamException.notEmpty(empIds, "员工不能为空");

        return Result.success(
                empInfoService.batchNoArrival(empIds, tokenUser)
        );
    }

    @Override
    @PutMapping("/onJobAgain")
    public Result<Integer> onJobAgain(@Valid @RequestBody EmpOnJobUpdateDTO updateDTO) {
        TokenUser tokenUser = UserContext.getUser();

        return Result.success(
                empInfoService.onJobAgain(updateDTO.getEmpId(), updateDTO.getFlowId(), tokenUser)
        );
    }

    @Override
    @PostMapping(value = "saveEmpInfoRelation")
    public Result<Boolean> saveEmpInfoRelation(@Valid @RequestBody EmpAllInfoAddDTO empAllInfoAddDTO) {
        TokenUser tokenUser = UserContext.getUser();

        if (empAllInfoAddDTO.getStatus() == null) {
            return Result.fail("请填写入职状态");
        }
        // 无员工性质设为其他
        if (empAllInfoAddDTO.getPostType() == null) {
            empAllInfoAddDTO.setPostType(PostType.OTHER.getValue());
        }

        Result result = checkEmpNumberAndPhone("", empAllInfoAddDTO.getCompanyId(), empAllInfoAddDTO.getPhone(), empAllInfoAddDTO.getNumber(), empAllInfoAddDTO.getStatus(), tokenUser);
        if (!result.getSuccess()) {
            return Result.fail(result.getMsg());
        }

        EmpInfoVO empInfoVO = empInfoService.saveEmpAllInfo(empAllInfoAddDTO, tokenUser);

        //更新员工的 “信息补充 未完善、已完善”
        List<String> list = new ArrayList<>();
        list.add(empInfoVO.getId());
        empInfoService.empCompleteInfo(list, tokenUser);

        return Result.success(true);
    }

    @Override
    @PostMapping(value = "saveEmpInfoRelationForMini")
    public Result<Boolean> saveEmpInfoRelationForMini(@Valid @RequestBody EmpAllInfoAddDTO empAllInfoAddDTO) {
        TokenUser tokenUser = UserContext.getUser();
        if(ObjectUtils.isEmpty(tokenUser)){
            String siteId = empAllInfoAddDTO.getSiteId();
            tokenUser = new TokenUser();
            tokenUser.setSiteId(siteId);
            tokenUser.setUserId("system");
        }
        // 将手动构建的token放入线程
        SecurityContext.setTokenData(tokenUser);
        SecurityContext.setToken(null);
        // 无员工性质设为其他
        if (empAllInfoAddDTO.getPostType() == null) {
            empAllInfoAddDTO.setPostType(PostType.OTHER.getValue());
        }
        Result result = checkEmpNumberAndPhone("", empAllInfoAddDTO.getCompanyId(), empAllInfoAddDTO.getPhone(),
                empAllInfoAddDTO.getNumber(), empAllInfoAddDTO.getStatus(), tokenUser);
        if (!result.getSuccess()) {
            return Result.fail(result.getMsg());
        }
        empInfoService.saveEmpAllInfo(empAllInfoAddDTO, tokenUser);
        return Result.success(true);
    }

    @Override
    @PostMapping(value = "saveEmpInfoAndRuleForMini")
    public Result<Boolean> saveEmpInfoAndRuleForMini(@Valid @RequestBody EmpInfoAndRuleAddDTO empInfoAndRuleAddDTO) {
        TokenUser tokenUser = UserContext.getUser();
        if(ObjectUtils.isEmpty(tokenUser)){
            String siteId = empInfoAndRuleAddDTO.getSiteId();
            tokenUser = new TokenUser();
            tokenUser.setSiteId(siteId);
            tokenUser.setUserId("system");
        }
        //TODO 临时设置成null
        empInfoAndRuleAddDTO.setUserId(null);

        if (empInfoAndRuleAddDTO.getStatus() == null) {
            return Result.fail("请填写入职状态");
        }
        // 无员工性质设为其他
        if (empInfoAndRuleAddDTO.getPostType() == null) {
            empInfoAndRuleAddDTO.setPostType(PostType.OTHER.getValue());
        }

        Result result = checkEmpNumberAndPhone("", empInfoAndRuleAddDTO.getCompanyId(), empInfoAndRuleAddDTO.getPhone(), empInfoAndRuleAddDTO.getNumber(), empInfoAndRuleAddDTO.getStatus(), tokenUser);
        if (!result.getSuccess()) {
            return Result.fail(result.getMsg());
        }

        empInfoService.saveEmpAllInfo(empInfoAndRuleAddDTO, tokenUser);
        return Result.success(true);
    }

    @Override
    @PostMapping(value = "saveEmpInfoAndRule")
    public Result<EmpInfoVO> saveEmpInfoAndRule(@Valid @RequestBody EmpInfoAndRuleAddDTO empInfoAndRuleAddDTO) {
        TokenUser tokenUser = UserContext.getUser();
        if (empInfoAndRuleAddDTO.getStatus() == null) {
            return Result.fail("请填写入职状态");
        }
        // 无员工性质设为其他
        if (empInfoAndRuleAddDTO.getPostType() == null) {
            empInfoAndRuleAddDTO.setPostType(PostType.OTHER.getValue());
        }
        CheckInPeopleVO checkInPeopleVO = checkInPeopleService.selectById(empInfoAndRuleAddDTO.getCheckInId(), tokenUser.getSiteId());
        if (checkInPeopleVO != null && StringUtils.isEmpty(checkInPeopleVO.getPhone())) {
            CheckInPeopleUpdateDTO checkInPeopleUpdateDTO = new CheckInPeopleUpdateDTO();
            checkInPeopleUpdateDTO.setId(empInfoAndRuleAddDTO.getCheckInId());
            checkInPeopleUpdateDTO.setStatus(empInfoAndRuleAddDTO.getPostType() == 2 ? 4 : null);
            checkInPeopleService.update(checkInPeopleUpdateDTO, tokenUser);
        }

        Result result = checkEmpNumberAndPhone("", empInfoAndRuleAddDTO.getCompanyId(), empInfoAndRuleAddDTO.getPhone(), empInfoAndRuleAddDTO.getNumber(), empInfoAndRuleAddDTO.getStatus(), tokenUser);
        if (!result.getSuccess()) {
            return Result.fail(result.getMsg());
        }

        EmpInfoVO empInfoVO = empInfoService.saveEmpAllInfo(empInfoAndRuleAddDTO, tokenUser);

        if (!StringUtils.isEmpty(empInfoAndRuleAddDTO.getUserId())) {
            tokenUser.setUserId(empInfoAndRuleAddDTO.getUserId());
        }

        //更新员工的 “信息补充 未完善、已完善”
        List<String> list = new ArrayList<>();
        list.add(empInfoVO.getId());
        empInfoService.empCompleteInfo(list, tokenUser);

        return Result.success(empInfoVO);
    }

    /**
     * 校验用户信息手机号和工号(不校验工号)
     *
     * @param id        id
     * @param companyId 公司id
     * @param phone     手机号
     * @param number    工号
     * @param tokenUser 当前用户
     * @return 校验结果
     */
    @Deprecated
    private Result checkEmpNumberAndPhone(String id, String companyId, String phone, String number, Integer status, TokenUser tokenUser) {
        if (!StringUtils.isEmpty(phone)) {
            EmpInfoVO empInfoVO = empInfoService.selectByPhone(companyId, phone, tokenUser.getSiteId());
            if (!Objects.isNull(empInfoVO)) {
                if (StringUtils.isEmpty(id) || !id.equals(empInfoVO.getId())) {
                    return Result.fail("手机号" + phone + "已被使用,请修改!");
                }
            }
        }
        // 不校验工号
        /*if (!StringUtils.isEmpty(number)) {
            EmpInfoVO empInfoVO = empInfoService.selectByNumber(companyId, number, tokenUser.getSiteId());
            if (!Objects.isNull(empInfoVO)) {
                if (StringUtils.isEmpty(id) || !id.equals(empInfoVO.getId())) {
                    return Result.fail("工号" + number + "已被使用,请修改!");
                }
            }
        }*/

        if (status != null && EmpInfoStatus.WAIT_ENTRY.equals(EmpInfoStatus.find(status))) {
            if (!StringUtils.isEmpty(phone)) {
                // 根据手机号查找可入职的用户信息
                List<EmpInfoListVO> empInfoList = empInfoService.listEntryByPhone(phone, tokenUser.getSiteId());
                if (!CollectionUtils.isEmpty(empInfoList)) {
                    for (EmpInfoListVO empInfoVO : empInfoList) {
                        if (!companyId.equals(empInfoVO.getCompanyId())) {
                            CompanyVO companyVO = companyService.selectBaseCompanyById(empInfoVO.getCompanyId(), tokenUser.getSiteId());
                            return Result.fail("当前员工在其他公司【" + companyVO.getName() + "】存在尚未完成的入职信息");
                        }
                    }
                }
            }
        }
        return Result.success();
    }

    @Override
    @PutMapping(value = "/updateEmpAllInfo")
    public Result<Integer> updateEmpAllInfo(@Valid @RequestBody EmpAllInfoDTO empAllInfoDTO) {
        TokenUser tokenUser = UserContext.getUser();

        EmpInfoDO empInfoDO = empInfoService.selectDOById(empAllInfoDTO.getId(), tokenUser.getSiteId());
        if (Objects.isNull(empInfoDO)) {
            throw new HrException("员工信息不正确");
        }
        // 不是本人的校验是否有修改权限
//        if (StringUtils.isEmpty(empInfoDO.getUserId()) ||
//                !empInfoDO.getUserId().equals(tokenUser.getUserId())) {
//            // todo 修改员工信息权限校验
//            PermissionException.isTrue(hrPermissionService.hasRight(tokenUser.getUserId(), tokenUser.getSiteId(), COMPANY_EMP_EDIT), PERMISSION_DENIED_MESSAGE);
//        }


        Result result = checkEmpNumberAndPhone(empInfoDO.getId(), empInfoDO.getCompanyId(), empAllInfoDTO.getPhone(), empAllInfoDTO.getNumber(), empAllInfoDTO.getStatus(), tokenUser);
        if (!result.getSuccess()) {
            return Result.fail(result.getMsg());
        }

        if (empAllInfoDTO.getCheckApp() != null && empAllInfoDTO.getCheckApp()) {
            //根据模块进行校验
            String necessary = empInfoService.necessary(empAllInfoDTO, empInfoDO, tokenUser.getSiteId());
            //根据字段进行校验
            //String checkField = empInfoService.checkField(empAllInfoDTO, empInfoDO.getCompanyId(), tokenUser.getSiteId());
            if (!StringUtils.isEmpty(necessary)) {
                return Result.fail(necessary);
            } else {
                empAllInfoDTO.setIsImprove(true);
            }
        }

        int count = empInfoService.updateEmpAllInfo(empAllInfoDTO, tokenUser);
        if (count == 0) {
            throw new ParamException("更新失败，请刷新页面后重试");
        }
        return Result.success(count);
    }

    @Override
    @GetMapping(value = "selectEmpInfoPageRelation")
    public Result<Page<EmpInfoListVO>> selectEmpInfoPageRelation(@Valid EmpInfoQuery empInfoQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        return Result.success(
                empInfoService.selectEmpInfoPageRelation(empInfoQuery, tokenUser)
        );
    }

    @Override
    @GetMapping(value = "selectEmpInfoALLRelation")
    public Result<Page<EmpInfoListVO>> pageEmpInfoALLRelation(@Valid EmpInfoQuery empInfoQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        return Result.success(
                empInfoService.pageOnJobEmpList(empInfoQuery, tokenUser)
        );
    }

    @Override
    @GetMapping(value = "selectIdNamePhoneOnJobEmpList")
    public Result<Page<EmpInfoListVO>> selectIdNamePhoneOnJobEmpList(@Valid String companyId, String empNameOrPhone
            , Integer pageNo, Integer pageSize) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        return Result.success(
                empInfoService.selectIdNamePhoneOnJobEmpList(companyId, empNameOrPhone, pageNo, pageSize, tokenUser)
        );
    }

    @Override
    @GetMapping(value = "listOnJobRelation")
    public Result<List<EmpInfoListVO>> listOnJobRelation(@Valid EmpInfoQuery empInfoQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        return Result.success(
                empInfoService.listOnJobEmpList(empInfoQuery, tokenUser)
        );
    }

    @Override
    @GetMapping(value = "listLeaveRelation")
    public Result<List<EmpInfoListVO>> listLeaveRelation(@Valid EmpInfoQuery empInfoQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        return Result.success(
                empInfoService.listLeaveRelation(empInfoQuery, tokenUser)
        );
    }

    @Override
    @GetMapping(value = "selectEmpInfoPendingRelation")
    public Result<Page<EmpInfoListVO>> selectEmpInfoPendingRelation(@Valid EmpInfoQuery empInfoQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        return Result.success(
                empInfoService.selectEmpInfoPendingRelation(empInfoQuery, tokenUser)
        );
    }

    @Override
    @GetMapping(value = "selectEmpInfoOnJobRelation")
    public Result<Page<EmpInfoListVO>> selectEmpInfoOnJobRelation(@Valid EmpInfoQuery empInfoQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        return Result.success(
                empInfoService.selectEmpInfoOnJobRelation(empInfoQuery, tokenUser)
        );
    }

    @Override
    @PostMapping(value = "/listPasteOnJob/{companyId}")
    public Result<CheckInEmpInfoListVO> listPasteOnJob(@RequestBody List<String> idCardList, @PathVariable String companyId) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        return Result.success(
                empInfoService.listPasteOnJob(idCardList, companyId, tokenUser)
        );
    }

    @Override
    @GetMapping(value = "/pageWaitJobAdvanced")
    public Result<Page<EmpInfoListVO>> pageWaitJobAdvanced(EmpInfoQuery empInfoQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        return Result.success(
                empInfoService.pageWaitJobAdvanced(empInfoQuery, tokenUser)
        );
    }

    @Override
    @GetMapping(value = "/pageResignedList")
    public Result<Page<EmpInfoListVO>> pageResignedList(EmpInfoQuery empInfoQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        return Result.success(
                empInfoService.pageResignedList(empInfoQuery, tokenUser)
        );
    }

    @Override
    @PostMapping(value = "/listPasteWaitJob/{companyId}")
    public Result<CheckInEmpInfoListVO> listPasteWaitJob(@RequestBody List<String> idCardList,
                                                         @PathVariable String companyId) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        return Result.success(
                empInfoService.listPasteWaitJob(idCardList, companyId, tokenUser)
        );
    }

    @Override
    @PostMapping(value = "/selectEmpInfoOnJobRelation/{companyId}")
    public Result<EmpInfoPasteVO> selectEmpInfoOnJobRelation(@RequestBody String[] idCards, @PathVariable String companyId) {
        TokenUser tokenUser = UserContext.getUser();

        return Result.success(empInfoService.selectEmpInfoOnJobRelationByIdCards(idCards, companyId, tokenUser));
    }

    @Override
    @GetMapping(value = "selectEmpInfoToFormalRelation")
    public Result<Page<EmpInfoListVO>> selectEmpInfoToFormalRelation(@Valid EmpInfoQuery empInfoQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        return Result.success(
                empInfoService.selectEmpInfoToFormalRelation(empInfoQuery, tokenUser)
        );
    }

    @Override
    @GetMapping(value = "/selectForLeave")
    public Result<Page<EmpInfoListVO>> selectForLeave(@Valid EmpInfoQuery empInfoQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        return Result.success(
                empInfoService.selectForLeave(empInfoQuery, tokenUser)
        );
    }

    @Override
    @PostMapping(value = "/listPasteFormal/{companyId}")
    public Result<CheckInEmpInfoListVO> listPasteFormal(@RequestBody List<String> idCardList,
                                                        @PathVariable String companyId) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        return Result.success(
                empInfoService.listPasteFormal(idCardList, companyId, tokenUser)
        );
    }

    @Override
    @PostMapping(value = "/listPasteFormalForLeave/{companyId}")
    public Result<CheckInEmpInfoListVO> listPasteFormalForLeave(@RequestBody List<String> idCardList,
                                                                @PathVariable String companyId) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        return Result.success(
                empInfoService.listPasteFormalForLeave(idCardList, companyId, tokenUser)
        );
    }

    @Override
    @GetMapping(value = "selectEmpInfoLeaveRelation")
    public Result<Page<EmpInfoListVO>> selectEmpInfoLeaveRelation(@Valid EmpInfoQuery empInfoQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        return Result.success(
                empInfoService.selectEmpInfoLeaveRelation(empInfoQuery, tokenUser)
        );
    }

    @Override
    @PostMapping(value = "/listPasteResigned/{companyId}")
    public Result<CheckInEmpInfoListVO> listPasteResigned(@RequestBody List<String> idCardList,
                                                          @PathVariable String companyId) {
        TokenUser tokenUser = UserContext.getUser();

        return Result.success(
                empInfoService.listPasteResigned(idCardList, companyId, tokenUser)
        );
    }

    @Override
    @PostMapping(value = "/listPasteWaitLeave/{companyId}")
    public Result<CheckInEmpInfoListVO> listPasteWaitLeave(@RequestBody List<String> idCardList,
                                                           @PathVariable String companyId) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        return Result.success(
                empInfoService.listPasteWaitLeave(idCardList, companyId, tokenUser)
        );
    }

    @Override
    @PostMapping(value = "/selectEmpInfoLeaveRelation/{companyId}")
    public Result<EmpInfoPasteVO> selectEmpInfoLeaveRelation(@RequestBody String[] idCards, @PathVariable String companyId) {
        TokenUser tokenUser = UserContext.getUser();

        return Result.success(empInfoService.selectEmpInfoLeaveRelationByIdCards(idCards, companyId, tokenUser));
    }


    @Override
    @GetMapping(value = "selectEmpInfoTransferRelation")
    public Result<Page<EmpInfoListVO>> selectEmpInfoTransferRelation(@Valid EmpInfoQuery empInfoQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        return Result.success(
                empInfoService.selectEmpInfoTransferRelation(empInfoQuery, tokenUser)
        );
    }

    @Override
    @PostMapping(value = "/listPasteTransferRelation/{companyId}")
    public Result<CheckInEmpInfoListVO> listPasteTransferRelation(@RequestBody List<String> idCardList,
                                                                  @PathVariable String companyId) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        return Result.success(
                empInfoService.listPasteTransferRelation(idCardList, companyId, tokenUser)
        );
    }

    @Override
    @GetMapping(value = "selectEmpInfoListForLeave")
    public Result<Page<EmpInfoListVO>> selectEmpInfoListForLeave(@Valid EmpInfoQuery empInfoQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        return Result.success(
                empInfoService.selectEmpInfoListForLeave(empInfoQuery, tokenUser)
        );
    }

    @Override
    @GetMapping(value = "pageOnJobEmpList")
    public Result<Page<EmpInfoListVO>> pageOnJobEmpList(@Valid EmpInfoQuery empInfoQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        return Result.success(
                empInfoService.pageOnJobEmpList(empInfoQuery, tokenUser)
        );
    }

    @Override
    @GetMapping(value = "getEmpCurrentPosition")
    public Result<EmpInfoCurrentPositionVO> getEmpCurrentPosition(@Valid EmpInfoQuery empInfoQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        return Result.success(
                empInfoService.getEmpCurrentPosition(empInfoQuery, tokenUser)
        );
    }


    @Override
    @GetMapping(value = "pageWaitFormal")
    public Result<Page<EmpInfoListVO>> pageOnJobWaitFormal(@Valid EmpInfoQuery empInfoQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        // 正式类型（1：试用期，2：已转正）
        empInfoQuery.setFormalType(FormalTypeEnum.PROBATION.getValue());
        return Result.success(
                empInfoService.pageOnJobEmpList(empInfoQuery, tokenUser)
        );
    }

    @Override
    @GetMapping(value = "pageHasFormal")
    public Result<Page<EmpInfoListVO>> pageHasFormal(@Valid EmpInfoQuery empInfoQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        // 正式类型（1：试用期，2：已转正）
        empInfoQuery.setFormalType(FormalTypeEnum.FORMAL.getValue());
        return Result.success(
                empInfoService.pageOnJobEmpList(empInfoQuery, tokenUser)
        );
    }

    @Override
    @GetMapping(value = "pageWaitLeave")
    public Result<Page<EmpInfoListVO>> pageWaitLeave(@Valid EmpInfoQuery empInfoQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        // 员工状态（1：待入职，2：入职，3：待离职，4：离职）
        empInfoQuery.setStatus(3);
        return Result.success(
                empInfoService.selectEmpInfoPageRelation(empInfoQuery, tokenUser)
        );
    }

    @Override
    @GetMapping(value = "pageHasLeave")
    public Result<Page<EmpInfoListVO>> pageHasLeave(@Valid EmpInfoQuery empInfoQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        // 员工状态（1：待入职，2：入职，3：待离职，4：离职）
        empInfoQuery.setStatus(4);
        return Result.success(
                empInfoService.selectEmpInfoPageRelation(empInfoQuery, tokenUser)
        );
    }

    @Override
    @GetMapping(value = "pageTransfer")
    public Result<Page<EmpInfoListVO>> pageTransfer(@Valid EmpInfoQuery empInfoQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        return Result.success(
                empInfoService.pageTransfer(empInfoQuery, tokenUser)
        );
    }

    @Override
    @GetMapping(value = "pageNoFormalType")
    public Result<Page<EmpInfoListVO>> pageNoFormalType(@Valid EmpInfoQuery empInfoQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验
        // 正式类型（1：试用期，2：已转正）
//        empInfoQuery.setFormalType(FormalTypeEnum.NOTYPE.getValue());
        return Result.success(
                empInfoService.pageOnJobEmpList(empInfoQuery, tokenUser)
        );
    }

    @Override
    @PostMapping(value = "empRegisterAccount")
    public Result<UserVO> empRegisterAccount(@Valid @RequestBody EmpInfoQuery empInfoQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        return Result.success(
                userProviderService.registerAccount(empInfoQuery.getName(), empInfoQuery.getPhone(), tokenUser, empInfoQuery.getCompanyId())
        );
    }

    @Override
    @GetMapping(value = "/findEmpInfoRelation/{empInfoId}")
    public Result<EmpAllInfoVO> findEmpInfoRelation(@PathVariable String empInfoId,
                                                    @RequestParam("companyId") String companyId) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看员工信息权限校验

        EmpAllInfoVO empAllInfoVO = empInfoService.findEmpInfoRelationAsync(empInfoId, tokenUser.getSiteId());
        if (Objects.nonNull(empAllInfoVO) && !companyId.equals(empAllInfoVO.getCompanyId())) {
            return Result.success();
        }
        return Result.success(empAllInfoVO);
    }

    @Override
    @GetMapping(value = "/findEmpInfoRelationForStatisticsPage/{empInfoId}")
    public Result<EmpAllInfoVO> findEmpInfoRelationForStatisticsPage(@PathVariable String empInfoId,
                                                                     @RequestParam("companyId") String companyId) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看员工信息权限校验

        EmpAllInfoVO empAllInfoVO = empInfoService.findEmpInfoRelation(empInfoId, tokenUser.getSiteId());

        return Result.success(empAllInfoVO);
    }

    @Override
    @GetMapping(value = "/findEmpInfoPosition/{empInfoId}")
    public Result<EmpInfoPositionVO> findEmpInfoPosition(@PathVariable String empInfoId,
                                                         @RequestParam("companyId") String companyId) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看员工信息权限校验
        if (StringUtils.isEmpty(companyId)) {
            return Result.fail("请传递公司id");
        }
        return Result.success(
                empInfoService.findEmpInfoPosition(companyId, empInfoId, tokenUser.getSiteId())
        );
    }

    @Override
    @PostMapping(value = "/entrySmsByIds")
    public Result<Integer> sendEntrySmsByIds(@RequestBody String[] empInfoIds) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看员工信息权限校验

        List<EmpInfoDO> empInfoList = new ArrayList<>();
        for (String empInfoId : empInfoIds) {
            EmpInfoDO empInfoDO = empInfoService.selectDOById(empInfoId, tokenUser.getSiteId());
            if (Objects.isNull(empInfoDO)) {
                return Result.fail("所选人员不存在或已删除");
            } else if (!EmpInfoStatus.WAIT_ENTRY.equals(EmpInfoStatus.find(empInfoDO.getStatus()))) {
                return Result.fail("'" + empInfoDO.getName() + "'不是待入职状态,请刷新页面,重新选择");
            } else {
                empInfoList.add(empInfoDO);
            }
        }
        if (CollectionUtils.isEmpty(empInfoList)) {
            return Result.fail("没有需要发送入职信息的人员");
        }

        return Result.success(
                empSendSmsService.sendEntrySms(empInfoList, tokenUser)
        );
    }

    @Override
    @PostMapping(value = "/entrySmsByCompany/{companyId}")
    public Result<Integer> sendEntrySmsByCompany(@PathVariable String companyId) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看员工信息权限校验

        // 该公司的待入职员工
        EmpInfoQuery empInfoQuery = new EmpInfoQuery();
        empInfoQuery.setCompanyId(companyId);
        empInfoQuery.setStatus(EmpInfoStatus.WAIT_ENTRY.getValue());

        List<EmpInfoDO> empInfoList = empInfoService.selectDO(empInfoQuery, tokenUser);
        if (CollectionUtils.isEmpty(empInfoList)) {
            return Result.fail("没有需要发送入职信息的人员");
        }

        return Result.success(
                empSendSmsService.sendEntrySms(empInfoList, tokenUser)
        );
    }

    @Override
    @GetMapping(value = "/pageEmpInfoByEmp/{companyId}")
    public Result<Page<EmpInfoListVO>> pageEmpInfoByDepAndEmpInfo(@PathVariable String companyId,
                                                                  @Valid DepAndInfoQuery depAndInfoQuery) {

        TokenUser tokenUser = UserContext.getUser();

        depAndInfoQuery.setCompanyId(companyId);
        return Result.success(
                empInfoService.pageEmpInfoByDepAndEmpInfo(depAndInfoQuery, tokenUser)
        );
    }

    @Override
    @PostMapping("/export")
    public ResponseEntity<Resource> export(@Valid @RequestBody EmpInfoExportQuery empInfoExportQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 导出权限校验
        // 要导出的数据
        String excelFilePath = empInfoService.selectExportList(empInfoExportQuery, tokenUser);
        // 编码文件名，防止乱码
        String filenames = FileKit.getNameAndEncode(excelFilePath);
        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=\"" + filenames + "\"")
                .header(HttpHeaders.CONTENT_TYPE, "application/vnd.ms-excel")
                .body(new FileSystemResource(excelFilePath));
    }

    @Override
    @PostMapping("/parse")
    public Result<List<ParseResultVO<EmpInfoImportDTO>>> parseImportFile(@RequestParam("file") MultipartFile file, @RequestParam(required = false) Boolean success) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 导入解析excel权限校验

        // 临时保存到本地
        String excelFilePath = FileKit.saveFileToLocal(file, null, null, new String[]{"xls", "xlsx"}, null);
        File excelFile = new File(excelFilePath);
        HrException.isTrue(excelFile.exists(), "文件上传失败");
        return Result.success(
                empInfoService.parseImportFile(excelFile, success, tokenUser)
        );
    }

    @Override
    @PostMapping("/import")
    public Result<EmpImportExcelVO> importFile(
            @RequestParam("file") MultipartFile file,
            @RequestParam(required = false) Boolean force,
            @RequestParam("companyId") String companyId) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 导入excel权限校验

        // 临时保存到本地
        String excelFilePath = FileKit.saveFileToLocal(file, null, null, new String[]{"xls", "xlsx"}, null);
        File excelFile = new File(excelFilePath);
        HrException.isTrue(excelFile.exists(), "文件上传失败");

        EmpImportExcelVO empImportExcelVO = empInfoService.importFile(excelFile, tokenUser, force, companyId);
        if (Objects.isNull(empImportExcelVO)) {
            return Result.fail("文件上传失败,请检查上传的模板");
        }

        return Result.success(empImportExcelVO);
    }

    @Override
    @PostMapping("/importZhiXinRen")
    public Result<EmpImportExcelVO> importFileZhiXinRen(@RequestParam("file") MultipartFile file,
            @RequestParam(required = false) Boolean force, @RequestParam("companyId") String companyId) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 导入excel权限校验

        // 临时保存到本地
        String excelFilePath = FileKit.saveFileToLocal(file, null, null, new String[]{"xls", "xlsx"}, null);
        File excelFile = new File(excelFilePath);
        HrException.isTrue(excelFile.exists(), "文件上传失败");

        EmpImportExcelVO empImportExcelVO = empInfoService.importFileZhiXinRen(excelFile, tokenUser, force, companyId);
        if (Objects.isNull(empImportExcelVO)) {
            return Result.fail("文件上传失败,请检查上传的模板");
        }

        return Result.success(empImportExcelVO);
    }

    @Override
    @PostMapping("/importZhiXinRenForSite")
    public Result<EmpImportExcelVO> importZhiXinRenForSite(
            @RequestParam("file") MultipartFile file, @RequestParam(required = false) Boolean force) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 导入excel权限校验

        // 临时保存到本地
        String excelFilePath = FileKit.saveFileToLocal(file, null, null, new String[]{"xls", "xlsx"}, null);
        File excelFile = new File(excelFilePath);
        HrException.isTrue(excelFile.exists(), "文件上传失败");

        EmpImportExcelVO empImportExcelVO = empInfoService.importZhiXinRenForSite(excelFile, tokenUser, force);
        if (Objects.isNull(empImportExcelVO)) {
            return Result.fail("文件上传失败,请检查上传的模板");
        }

        return Result.success(empImportExcelVO);
    }

    @Override
    @PostMapping("/importFileZhiXinRenForUpdate")
    public Result<EmpImportExcelVO> importFileZhiXinRenForUpdate(
            @RequestParam("file") MultipartFile file,
            @RequestParam(required = false) Boolean force,
            @RequestParam("companyId") String companyId) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 导入excel权限校验

        // 临时保存到本地
        String excelFilePath = FileKit.saveFileToLocal(file, null, null, new String[]{"xls", "xlsx"}, null);
        File excelFile = new File(excelFilePath);
        HrException.isTrue(excelFile.exists(), "文件上传失败");

        EmpImportExcelVO empImportExcelVO = empInfoService.importFileZhiXinRenForUpdate(excelFile, tokenUser, force, companyId);
        if (Objects.isNull(empImportExcelVO)) {
            return Result.fail("文件上传失败,请检查上传的模板");
        }

        return Result.success(empImportExcelVO);
    }


    @Override
    @PostMapping("/exportByEmpIds")
    public ResponseEntity<Resource> exportByEmpIds(@Valid @RequestBody List<String> empIds, String companyId) {
        TokenUser tokenUser = UserContext.getUser();

        // 要导出的数据
        String excelFilePath = empInfoService.exportByEmpIds(empIds, companyId, tokenUser);
        // 编码文件名，防止乱码
        String filenames = FileKit.getNameAndEncode(excelFilePath);
        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=\"" + filenames + "\"")
                .header(HttpHeaders.CONTENT_TYPE, "application/vnd.ms-excel")
                .body(new FileSystemResource(excelFilePath));
    }

    @Override
    @PostMapping(value = "/getEmpInfoListForContract")
    public Result<List<EmpInfoContractVO>> getEmpInfoListForContract(Long templateId, @Valid String... empIdArray) {
        TokenUser tokenUser = UserContext.getUser();
        ParamException.notNull(templateId, "请先选择模板");
        ParamException.isFalse(empIdArray == null || empIdArray.length == 0, "请先选择员工");
        // todo 查看员工信息权限校验

        return Result.success(
                empInfoService.getEmpInfoListForContract(empIdArray, templateId, tokenUser.getSiteId())
        );
    }

    @Override
    @PostMapping(value = "/getContractEmpInfoList")
    public Result<List<EmpInfoContractVO>> getContractEmpInfoList(@Valid @RequestBody ContractEmpInfoDTO contractEmpInfoDTO) {
        TokenUser tokenUser = UserContext.getUser();

        return Result.success(
                empInfoService.getEmpContractInfoList(contractEmpInfoDTO, tokenUser.getSiteId())
        );
    }

    @Override
    @GetMapping(value = "/listEmpJoinCity/{companyId}")
    public Result<Map<String, String>> listEmpJoinCity(@PathVariable String companyId) {
        TokenUser tokenUser = UserContext.getUser();

        // todo 查看员工信息权限校验

        return Result.success(
                empInfoService.listEmpJoinCity(companyId, tokenUser.getSiteId())
        );
    }

    @Override
    @PostMapping(value = "/sendChangePhoneMessage/{empPhone}/{newPhone}")
    public Result<String> sendChangePhoneMessage(@PathVariable String empPhone,
                                                 @PathVariable String newPhone) {
        TokenUser tokenUser = UserContext.getUser();

        boolean sendResult = empInfoService.sendChangePhoneMessage(empPhone, newPhone, tokenUser);
        if (sendResult) {
            return Result.success("发送成功");
        } else {
            return Result.fail("发送失败");
        }
    }

    @Override
    @PutMapping(value = "/updateEmpPhone/{empPhone}/{newPhone}/{captcha}")
    public Result<String> updateEmpPhone(@PathVariable String empPhone,
                                         @PathVariable String newPhone,
                                         @PathVariable String captcha) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看员工信息权限校验

        empInfoService.updateEmpPhone(empPhone, newPhone, captcha, tokenUser);

        return Result.success("修改成功");
    }

    @Override
    @PostMapping(value = "/screenEmp")
    public Result<List<EmpInfoListVO>> screenEmp(@Valid @RequestBody EmpInfoScreenDTO empInfoScreenDTO) {
        TokenUser tokenUser = UserContext.getUser();

        // todo 查看员工信息权限校验

        return Result.success(
                empInfoService.screenEmp(empInfoScreenDTO, tokenUser)
        );
    }

    @Override
    @GetMapping(value = "/pinyinSet")
    public Result<Integer> piny() {
        TokenUser tokenUser = UserContext.getUser();

        // todo 查看员工信息权限校验

        return Result.success(
                empInfoService.pinyin(tokenUser)
        );
    }


    @Override
    @PutMapping(value = "/empChangeCompanyId")
    public Result<String> empChangeCompanyId(@RequestBody @Valid EmpChangeCompanyDTO empChangeCompanyDTO) {
        TokenUser tokenUser = UserContext.getUser();

        String errorString = empInfoService.empChangeCompanyId(empChangeCompanyDTO, tokenUser);
        if (errorString != null) {
            return Result.fail(errorString);
        }
        return Result.success("员工更换公司成功");
    }

    @Override
    @PutMapping(value = "/empBatchChangeCompanyId")
    public Result<String> empBatchChangeCompanyId(@RequestBody @Valid EmpBatchChangeCompanyDTO empBatchChangeCompanyDTO) {
        TokenUser tokenUser = UserContext.getUser();


        String errorString = empInfoService.empBatchChangeCompanyId(empBatchChangeCompanyDTO, tokenUser);
        if (errorString != null) {
            return Result.fail(errorString);
        }
        return Result.success("员工更换公司成功");
    }

    @Override
    @PutMapping(value = "/reinstatement")
    public Result<String> reinstatement(@Valid String companyId, String empId) {
        TokenUser tokenUser = UserContext.getUser();
        Integer reinstatement = empInfoService.reinstatement(companyId, empId, tokenUser);
        if (reinstatement < 1) {
            return Result.fail("员工恢复在职失败，请刷新后重试");
        }
        return Result.success("员工恢复在职成功");
    }

    @Override
    @PutMapping(value = "/reinstatement/{companyId}")
    public Result<Integer> batchReinstatement(@PathVariable String companyId, @RequestBody String[] empIds) {
        TokenUser tokenUser = UserContext.getUser();

        return Result.success(
                empInfoService.batchReinstatement(companyId, empIds, tokenUser)
        );
    }

    @Override
    @GetMapping(value = "/pageReinstatementEmp")
    public Result<Page<EmpInfoListVO>> pageReinstatementEmp(EmpInfoQuery empInfoQuery) {
        TokenUser tokenUser = UserContext.getUser();

        return Result.success(
                empInfoService.pageReinstatementEmp(empInfoQuery, tokenUser)
        );
    }

    @Override
    @PostMapping("/listPasteReinstatementEmp/{companyId}")
    public Result<CheckInEmpInfoListVO> listPasteReinstatementEmp(@RequestBody List<String> idCardList,
                                                                  @PathVariable String companyId) {
        TokenUser tokenUser = UserContext.getUser();

        return Result.success(
                empInfoService.listPasteReinstatementEmp(idCardList, companyId, tokenUser)
        );
    }

    @Override
    @GetMapping(value = "/pageByFill")
    public Result<Page<EmpInfoDO>> pageByFill(@Valid EmpSocPageQuery empSocPageQuery) {
        TokenUser tokenUser = UserContext.getUser();
        return Result.success(
                empInfoService.pageByFill(empSocPageQuery, tokenUser.getSiteId())
        );
    }

    @Override
    @GetMapping(value = "/increaseSiftEmp")
    public Result<Page<EmpInfoDO>> increaseSiftEmp(@Valid EmpSocPageQuery empSocPageQuery) {
        TokenUser tokenUser = UserContext.getUser();
        return Result.success(
                empInfoService.increaseSiftEmp(empSocPageQuery, tokenUser.getSiteId())
        );
    }

    @Override
    @GetMapping(value = "/increaseSiftEmpCount/{companyId}")
    public Result<List<SiftEmpCountVO>> increaseSiftEmpCount(@PathVariable String companyId) {
        TokenUser tokenUser = UserContext.getUser();
        return Result.success(
                empInfoService.increaseSiftEmpCount(companyId, tokenUser)
        );
    }

    @Override
    @GetMapping(value = "/decreaseSiftEmp")
    public Result<Page<EmpInfoDO>> decreaseSiftEmp(@Valid EmpSocPageQuery empSocPageQuery) {
        TokenUser tokenUser = UserContext.getUser();
        return Result.success(
                empInfoService.decreaseSiftEmp(empSocPageQuery, tokenUser.getSiteId())
        );
    }

    @Override
    @GetMapping(value = "/decreaseSiftEmpCount/{companyId}")
    public Result<List<SiftEmpCountVO>> decreaseSiftEmpCount(@PathVariable String companyId) {
        TokenUser tokenUser = UserContext.getUser();
        return Result.success(
                empInfoService.decreaseSiftEmpCount(companyId, tokenUser)
        );
    }

    @Override
    @PostMapping(value = "/selectEmpGroupByIdCards/{companyId}")
    public Result<EmpInfoPasteVO> selectEmpGroupByIdCards(@RequestBody String[] idCards, @PathVariable String companyId) {
        TokenUser tokenUser = UserContext.getUser();

        return Result.success(empInfoService.selectEmpGroupByIdCards(idCards, companyId, tokenUser));
    }

    @Override
    @PostMapping(value = "/selectEmpGroupByIdCards2/{companyId}")
    public Result<EmpInfoPasteVO> selectEmpGroupByIdCards2(@RequestBody String[] idCards, @PathVariable String companyId) {
        TokenUser tokenUser = UserContext.getUser();

        return Result.success(empInfoService.selectEmpGroupByIdCards2(idCards, companyId, tokenUser));
    }


    @Override
    @PostMapping(value = "/selectEmpSocByEmpIdList")
    public Result<Page<EmpSocDetailsVO>> selectEmpSocByEmpIdList(@Valid @RequestBody EmpSocTransformQuery empSocTransformQuery) {
        TokenUser tokenUser = UserContext.getUser();
        return Result.success(
                empInfoService.selectEmpSocByEmpIdList(empSocTransformQuery, tokenUser)
        );
    }

    @Override
    @GetMapping(value = "/selectDifferenceEmp")
    public Result<Page<EmpInfoDO>> selectDifferenceEmp(@Valid EmpSocPageQuery empSocPageQuery) {
        TokenUser tokenUser = UserContext.getUser();
        return Result.success(
                empInfoService.selectDifferenceEmp(empSocPageQuery, tokenUser)
        );
    }

    @Override
    @PostMapping(value = "/pasteIdCardSelect/{companyId}")
    public Result<EmpInfoPasteVO> pasteIdCardSelect(@PathVariable String companyId, @RequestBody String[] idCards) {
        TokenUser tokenUser = UserContext.getUser();
        return Result.success(
                empInfoService.pasteIdCardSelect(idCards, companyId, tokenUser)
        );
    }

    @Override
    @GetMapping(value = "/selectEmpListByPostType")
    public Result<List<EmpPostTypeListVO>> selectEmpListByPostType(String companyId, Integer formalType) {
        TokenUser tokenUser = UserContext.getUser();
        ParamException.notNull(companyId, "请选择公司");
        ParamException.notNull(formalType, "请先选择员工类型");
        return Result.success(empInfoService.selectEmpListByPostType(companyId, formalType, tokenUser));
    }

    @Override
    @GetMapping(value = "/pageEmpList")
    public Result<Page<EmpInfoVO>> pageEmpList(@Valid EmpListQuery empListQuery) {
        TokenUser tokenUser = UserContext.getUser();

        return Result.success(empInfoService.pageEmpList(empListQuery, tokenUser));
    }

    @Override
    @PostMapping(value = "/empListByIdCards/{companyId}")
    public Result<EmpInfoPasteVO> empListByIdCards(@RequestBody String[] idCards, @PathVariable String companyId) {
        TokenUser tokenUser = UserContext.getUser();

        return Result.success(empInfoService.empListByIdCards(idCards, companyId, tokenUser));
    }

    @Override
    @GetMapping(value = "/selectByPhoneNameIdCard")
    public Result<List<EmpInfoVO>> selectByPhoneNameIdCard(@Valid String phoneNameIdCard) {
        TokenUser tokenUser = UserContext.getUser();

        PermissionException.isTrue(hrPermissionService.hasRight(tokenUser.getUserId(), tokenUser.getSiteId()
                , COMPANY_PEOPLE_LIST), PERMISSION_DENIED_MESSAGE);
        return Result.success(empInfoService.selectByPhoneNameIdCard(phoneNameIdCard, tokenUser));
    }

    @Override
    @GetMapping(value = "/selectPageByPhoneNameIdCard")
    public Result<Page<EmpInfoVO>> selectPageByPhoneNameIdCard(@Valid String phoneNameIdCard, int pageNo, int pageSize) {
        TokenUser tokenUser = UserContext.getUser();

        PermissionException.isTrue(hrPermissionService.hasRight(tokenUser.getUserId(), tokenUser.getSiteId()
                , COMPANY_PEOPLE_LIST), PERMISSION_DENIED_MESSAGE);
        return Result.success(
                empInfoService.selectPageByPhoneNameIdCard(phoneNameIdCard, pageNo, pageSize, tokenUser)
        );
    }

    @Override
    @PutMapping("/updateSalaryRule")
    public Result<Integer> updateSalaryRule(SalaryRuleDTO salaryRuleDTO) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 修改员工信息权限校验

        int count = empInfoService.updateSalaryRule(salaryRuleDTO, tokenUser);
        if (count == 0) {
            throw new ParamException("更新失败，请刷新页面后重试");
        }
        return Result.success(count);
    }

    @Override
    @GetMapping("/selectUserInfoById")
    public Result<UserSettingVO> selectUserInfoById(String userId) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看员工信息权限校验

        // 直接查看user表中的信息
        List<UserDO> userDOList = userProviderService.selectUserByIds(Collections.singletonList(userId));
        if (CollectionUtils.isEmpty(userDOList)) {
            return Result.success();
        }
        UserSettingVO userSettingVO = userDOList.get(0).to(UserSettingVO.class);
        ThirdInfoDO thirdInfoDO = userProviderService.selectUserSettingById(userId);
        if (thirdInfoDO != null) {
            userSettingVO.setWechatName(thirdInfoDO.getNickName());
        }
        userSettingVO.setIsBindWechat(thirdInfoDO != null);
        return Result.success(
                userSettingVO
        );
    }


    @Override
    @PostMapping("/unbindWechatByUserId")
    public Result<String> unbindWechatByUserId(@RequestBody @Valid UnbindWechatDTO unbindWechatDTO) {
        // todo 修改员工信息权限校验

        TokenUser tokenUser = UserContext.getUser();

        //删除第三方信息表，下次登录会走绑定流程
        userProviderService.unbindWechatByUserId(unbindWechatDTO.getUserId());
        return Result.success();
    }

    @Override
    @PostMapping("/updatePhone")
    public Result<String> updatePhone(@Valid @RequestBody UpdateByPhoneDTO updateByPhoneDTO) {
        TokenUser tokenUser = UserContext.getUser();

        empInfoService.updatePhoneByVoucher(updateByPhoneDTO, tokenUser);
        return Result.success();
    }

    @Override
    @PostMapping("/empCount")
    public Result<EmpCountVO> empCount(@Valid @RequestBody EmpCountQuery empCountQuery) {
        TokenUser tokenUser = UserContext.getUser();

        return Result.success(
                empInfoService.empCount(empCountQuery, tokenUser)
        );
    }

    @Override
    @PostMapping("/pageEmpListForMini")
    public Result<Page<EmpInfoVO>> pageEmpListForMini(@Valid @RequestBody EmpCountQuery empCountQuery) {
        TokenUser tokenUser = UserContext.getUser();

        return Result.success(
                empInfoService.pageEmpListForMini(empCountQuery, tokenUser)
        );
    }

    @Override
    @GetMapping("/selectByEmpId")
    public Result<MyEmpInfoVO> selectByEmpId(@RequestParam String empId) {
        TokenUser tokenUser = UserContext.getUser();

        return Result.success(
                empInfoService.selectByEmpId(empId, tokenUser)
        );
    }

    @Override
    @GetMapping("/selectCurrentMonthByCompanyId")
    public Result<Page<EmpInfoVO>> selectCurrentMonthByCompanyId(String companyId, String nameOrPhone
            , int yearly, int monthly, int pageNo, int pageSize) {
        TokenUser tokenUser = UserContext.getUser();

        return Result.success(
                empInfoService.selectCurrentMonthByCompanyId(companyId, nameOrPhone, yearly, monthly, pageNo, pageSize, tokenUser)
        );
    }

    @Override
    @GetMapping("/pageSalaryFile")
    public Result<Page<EmpInfoVO>> pageNoFixSalaryFile(EmpInfoQuery empInfoQuery) {
        TokenUser tokenUser = UserContext.getUser();

        return Result.success(
                empInfoService.pageNoFixSalaryFile(empInfoQuery, tokenUser)
        );
    }

    @Override
    @PostMapping("/selectNoFixSalaryFileGroupByIdCards/{companyId}")
    public Result<EmpInfoPasteVO> selectNoFixSalaryFileGroupByIdCards(@RequestBody String[] idCards, @PathVariable String companyId) {
        TokenUser tokenUser = UserContext.getUser();

        return Result.success(
                empInfoService.selectNoFixSalaryFileGroupByIdCards(idCards, companyId, tokenUser)
        );
    }

    @Override
    @GetMapping("/selectResignedByPhoneAndIdCard")
    public Result<EmpInfoCheckVO> selectResignedByPhoneAndIdCard(@Valid String companyId, String phone, String idCard) {
        TokenUser tokenUser = UserContext.getUser();

        return Result.success(
                empInfoService.selectResignedByPhoneAndIdCard(companyId, phone, idCard, tokenUser)
        );
    }

    @Override
    @GetMapping("/selectPageByPostType")
    public Result<Page<EmpInfoDO>> selectPageByPostType(EmpInfoQuery empInfoQuery) {
        TokenUser tokenUser = UserContext.getUser();

        return Result.success(
                empInfoService.selectPageByPostType(empInfoQuery, tokenUser)
        );
    }

    @Override
    @GetMapping(value = "selectAllByEmpInfoQuery")
    public Result<Page<EmpInfoListVO>> selectAllByEmpInfoQuery(@Valid EmpInfoQuery empInfoQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        return Result.success(
                empInfoService.selectAllByEmpInfoQuery(empInfoQuery, tokenUser)
        );
    }
    @Override
    @PostMapping(value = "selectAllByCompanyIdAndIdCard")
    public Result<CheckInEmpInfoListVO> selectAllByCompanyIdAndIdCard(@Valid @RequestBody CheckInEmpInfoQuery checkInEmpInfoQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        return Result.success(
                empInfoService.selectAllByCompanyIdAndIdCard(checkInEmpInfoQuery.getCompanyId()
                        , checkInEmpInfoQuery.getCardList(), tokenUser)
        );
    }

    @GetMapping(value = "selectByCompanyId")
    public Result<List<EmpInfoVO>> selectByCompanyId(
            @RequestParam("companyId") String companyId,
            @RequestParam(value = "nameOrPhone", required = false) String nameOrPhone) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        return Result.success(
                empInfoService.selectByCompanyId(companyId, nameOrPhone, false, tokenUser)
        );
    }

    @Override
    @GetMapping(value = "getEmpFieldList")
    public Result<List<EmpFieldDTO>> getEmpFieldList(@Valid Integer queryType, String empId, String onboardingCompanyId) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        return Result.success(
                empInfoService.getEmpFieldList(queryType, empId, onboardingCompanyId, tokenUser)
        );
    }

    @PostMapping(value = "/selectSiteEmpStickupSelect")
    public Result<EmpInfoPasteVO> selectSiteEmpStickupSelect(@RequestBody List<String> idCardList) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看员工信息权限校验
        return Result.success(
                empInfoExtraService.selectSiteEmpStickupSelect(idCardList, tokenUser)
        );
    }

    @GetMapping(value = "/selectSiteEmp")
    public Result<Page<EmpInfoVO>> selectSiteEmp(@Valid EmpInfoQuery empInfoQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看员工信息权限校验

        return Result.success(
                empInfoExtraService.selectSiteEmp(empInfoQuery, tokenUser)
        );
    }


//    @Override
    @PostMapping("/downIdCard")
    public ResponseEntity<Resource> downIdCard(@Valid @RequestBody HrEmpInfoDownloadDTO hrEmpInfoDownloadDTO) {
        TokenUser tokenUser = UserContext.getUser();

        String zipName = "身份证导出";

        // 文件路径，只是用于临时目录存储
        String tempFilePath = empInfoExtraService.downIdCard(hrEmpInfoDownloadDTO,tokenUser);
        FileSystemResource resource = new FileSystemResource(tempFilePath);
        if (!resource.exists()) {
            throw new ParamException("系统错误，文件不存在或已被删除");
        }

        // 文件名编码
//        String filenames = new String(zipName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
        String filenames = FileKit.getNameAndEncode(zipName);
        MediaType mimeType = FileUtil.guessMimeType(zipName);
        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, DOWNLOAD_TYPE_ATTACHMENT + ";filename=\"" + filenames + "\"")
                .contentType(mimeType)
                .body(resource);
    }


}

